
/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-06-23     Lyons        first version
 */

#include <getopt.h>

/**
  * @brief Define Command-line Interface Command Buffer Max Length, Byte
  */

#ifdef  SHELL_CMD_SIZE
#define CLI_CMD_SIZE (SHELL_CMD_SIZE)
#else
#define CLI_CMD_SIZE (256)
#endif

/**
  * @brief Define Command-line Interface Controller Structure
  */

struct xcli
{
	int argc;
	char **argv;

    char *arg_filename;
    int arg_debug : 1;
    int arg_trace : 1;

    char *filename;
    int run   : 1;
    int mode  : 1;
    int debug : 1;
    int trace : 1;
    struct _cmd
    {
        char command[CLI_CMD_SIZE];
        int submit;
    } cmd;
};

static void cmd_version(void)
{
    DEBUG_D("XEmu utility, version-%s\n", "v1.0");
}

static void cmd_help(void)
{
    DEBUG_D("Usage: xemu [ OPTIONS ]\n"
            "       xemu [ OPTIONS ] --file filename\n"
            "where  OPTIONS := { -v[ersion] | -h[elp] | -d[ebug] | -t[race] }\n");
}

static int cli_parse(struct xcli *cli, int argc, char *argv[])
{
	static const struct option long_options[] = {
		{ "version",    no_argument,		NULL, 'v' },
		{ "help",		no_argument,		NULL, 'h' },
		{ "debug",		no_argument,		NULL, 'd' },
		{ "trace",		no_argument,		NULL, 't' },
		{ "file",		required_argument,	NULL, 'f' },
		{ NULL,         0,                  NULL, 0   }
	};

    int opt;

	while ( (opt = getopt_long(argc, argv, ":vhdtf:",
                                long_options, NULL)) >= 0)
    {
		switch (opt)
        {
            case 'v':
                cmd_version();
                return EXIT_SUCCESS;
            case 'h':
                cmd_help();
                return EXIT_SUCCESS;
            case 'd':
                cli->arg_debug = 1;
                DEBUG_D("[INFO] type twice 'Ctrl + d' to start running.\n");
                break;
            case 't':
                cli->arg_trace = 1;
                break;
            case 'f':
                cli->run = 1;
                cli->arg_filename = optarg;
                break;
            case ':':
                DEBUG_D("-%c option requires an argument\n", optopt);
                return EXIT_FAILURE;
            default:
                DEBUG_D("Unknown option.\n");
                return EXIT_FAILURE;
		}
	}

#ifdef DEBUG_PRINT_TRACE
    cli->arg_trace = 1;
#endif

    return EXIT_SUCCESS;
}
